/**
 * Created by meiguizhinian on 2018/6/28
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//TODO：等待完成
//cocos2dx class
ivy.ClipAniPlayer = ivy.BaseAniPlayer.extend({
	ctor : function () {
		this._super();
		this._runningLightVec = [];
		this._customFSHShaderFileName = "";
		this._createOverlapShaderSpriteFuncMap = new LLDictionary();
		this._updateOverlapShaderSpriteFuncMap = {};
		this._updateEndOverlapShaderSpriteFuncMap = new LLDictionary();
		this._runningShaderSpriteMap = new LLDictionary();
	},
	getPlayerType : function() {
		return ivy.AniPlayerType.eClip;
	},

	// ClipAniPlayer* clone(bool isHold = false) override;

	resetAnimation : function(animationID) {
		let animationDataPtr = ivy.EditorDataManager.getInstance().getAnimationDataBy(animationID.classID);
		if (animationDataPtr == null)
			return;
		if (animationDataPtr.get() === this._animationData.get()) {
			this.setActionID(animationID.actionID);
			this.setSequenceID(animationID.sequenceID);
			this.setPlayState(animationID.playState);
			this.setPlayType(animationID.playType);
		} else {
			ivy.Tools.pushFunctionToCocosThread(function(){
				this.setAnimationData(animationDataPtr);
				this.setAnimationID(animationID.classID);
				this.setActionID(animationID.actionID);
				this.setSequenceID(animationID.sequenceID);
				this.setPlayState(animationID.playState);
				this.setPlayType(animationID.playType);
				this.initAllPlayerAniChildren();
			}.bind(this));
		}
	},

	reset : function() {
		this.setActionID(this._actionIDBak);
	},
	setPlayState : function(state, autoResetSeqID=true) {
		this._playState = state;
		this.setNeedRefreshSpriteChildren(true);
		if (autoResetSeqID) {
			this.autoSetSequenceID();
		}
		this._isPlayEnd = false;
	},

	setPlayType : function(type, autoResetSeqID=true) {
		this._playType = type;
		this.setNeedRefreshSpriteChildren(true);
		if(autoResetSeqID) {
			this.autoSetSequenceID();
		}
		this._isPlayEnd = false;
	},

	autoSetSequenceID : function() {
		if (this._playType === ivy.AniPlayType.eReverse) {
			this._sequenceID = this._animationData.getActionSequenceCount(this.actionID_) - 1;
		} else {
			this._sequenceID = 0;
		}
		this._actionSequenceDuration = 0.0;
	},

	setActionID : function(actionID,resetSequence=true) {
		if (!resetSequence) {
			if (this.actionID_ === actionID) {
				return;
			}
		}
		//needCheckVaild
		this.actionID_ = actionID;
		this._actionIDBak = this.actionID_;
		this.autoSetSequenceID();
		this.setNeedRefreshSpriteChildren(true);
		this._isPlayEnd = false;
	},

	getActionCount : function() {
		return this._animationData.getActionCount();
	},

	getSequenceCount : function(actionID=null) {
		if (actionID) {
			if(actionID>=0 && actionID<this.getActionCount())
				return this._animationData.getActionSequenceCount(actionID);
			return 0;
		} else {
			return this._animationData.getActionSequenceCount(this.actionID_);
		}
	},

	setSequenceID : function(seqID) {
		this._sequenceID = seqID;
		this._actionSequenceDuration = 0;
		this.setNeedRefreshSpriteChildren(true);
		this._isPlayEnd = false;
	},

	getSuitChangeID : function(imgID) {
		return this._suitChangeMap.get(imgID) || -1;
	},

	setSuitChange : function(imgID, suitID)  {
		if (suitID >= 0) {
			this._suitChangeMap.set(imgID, suitID);
		} else {
			this._suitChangeMap.erase(imgID);
		}
	},

	clearSuitChangeData : function() {
		this._suitChangeMap.clear();
	},

	isKeyFrameDataNeedToDeal : function() {
		return this._animationData.isKeyFrame(this.actionID_, this._sequenceID);
	},


	/**
	 * getKeyFrameBaseData(cc::AnimationData::KeyFrameBaseType type)
	 * getKeyFrameBaseData(int32_t actionID, int32_t seqID, cc::AnimationData::KeyFrameBaseType type)
	 * */
	getKeyFrameBaseData : function(typeOrActionID, seqID, type) {
		if (seqID===undefined || type===undefined) {
			return this.getKeyFrameBaseData(this.actionID_, this._sequenceID, typeOrActionID);
		} else {
			if (this._animationData) {
				return this._animationData.getKeyFrameBaseData(typeOrActionID, seqID, type);
			}
			return 0;
		}
	},

	/**
	 * getKeyFrameCustomData(int32_t type)
	 * getKeyFrameCustomData(int32_t actionID, int32_t seqID, int32_ttype)
	 * */
	getKeyFrameCustomData : function(typeOrActionID, seqID, type) {
		if (seqID===undefined || type===undefined) {
			return this.getKeyFrameCustomData(this.actionID_, this._sequenceID, typeOrActionID);
		} else {
			if (this._animationData) {
				return this._animationData.getKeyFrameCustomData(typeOrActionID, seqID, type);
			}
			return 0;
		}
	},

	/**
	 * getKeyFrameCustomZoneData(int32_t type)
	 * getKeyFrameCustomZoneData(int32_t actionID, int32_t seqID, int32_ttype)
	 * */
	getKeyFrameCustomZoneData : function(typeOrActionID, seqID, type) {
		if (seqID===undefined || type===undefined) {
			return this.getKeyFrameCustomZoneData(this.actionID_, this._sequenceID, typeOrActionID);
		} else {
			if (this._animationData) {
				return this._animationData.getKeyFrameCustomZoneData(typeOrActionID, seqID, type);
			}
			return cc.rect(-1,-1,-1,-1);
		}
	},

	/**
	 * getKeyFrameBaseData(cc::AnimationData::KeyFrameBaseType type)
	 * getKeyFrameBaseData(int32_t actionID, int32_t seqID, cc::AnimationData::KeyFrameBaseType type)
	 * */
	isKeyFrameBaseDataExist : function(typeOrActionID, seqID, type) {
		if (seqID===undefined || type===undefined) {
			return this.isKeyFrameBaseDataExist(this.actionID_, this._sequenceID, typeOrActionID);
		} else {
			if (this._animationData) {
				return this._animationData.isKeyFrameBaseDataExist(typeOrActionID, seqID, type);
			}
			return false;
		}
	},

	/**
	 * getKeyFrameCustomZoneData(int32_t type)
	 * getKeyFrameCustomZoneData(int32_t actionID, int32_t seqID, int32_ttype)
	 * */
	isKeyFrameCustomDataExist : function(typeOrActionID, seqID, type) {
		if (seqID===undefined || type===undefined) {
			return this.isKeyFrameCustomDataExist(this.actionID_, this._sequenceID, typeOrActionID);
		} else {
			if (this._animationData) {
				return this._animationData.isKeyFrameCustomDataExist(typeOrActionID, seqID, type);
			}
			return false;
		}
	},

	/**
	 * getKeyFrameCustomZoneData(int32_t type)
	 * getKeyFrameCustomZoneData(int32_t actionID, int32_t seqID, int32_ttype)
	 * */
	isKeyFrameCustomZoneDataExist : function(typeOrActionID, seqID, type) {
		if (seqID===undefined || type===undefined) {
			return this.isKeyFrameCustomZoneDataExist(this.actionID_, this._sequenceID, typeOrActionID);
		} else {
			if (this._animationData) {
				return this._animationData.isKeyFrameCustomZoneDataExist(typeOrActionID, seqID, type);
			}
			return false;
		}
	},

	getAttackBox : function() {
		if (this._animationData)
			return this._animationData.getAttackBox(this.actionID_, this._sequenceID);
		return cc.rect(-1,-1,-1,-1);
	},
	getCollisionBox : function() {
		if (this._animationData)
			return this._animationData.getCollisionBox(this.actionID_, this._sequenceID);
		return cc.rect(-1,-1,-1,-1);
	},

	setShowColAtkBoxRect : function(show, forceSet=false) {
		if (this.showColAtkBox === show && !forceSet)
			return;
		this.showColAtkBox = show;
		if (this.showColAtkBox) {
			if (forceSet) {
				this.colBoxDrawNode = new cc.DrawNode();
				this.addChild(this.colBoxDrawNode, 1000);
				this.atkBoxDrawNode = new cc.DrawNode();
				this.addChild(this.atkBoxDrawNode, 1000);
			} else {
				if (!this.colBoxDrawNode) {
					this.colBoxDrawNode = new cc.DrawNode();
					this.addChild(this.colBoxDrawNode, 1000);
				}
				if (!this.atkBoxDrawNode) {
					this.atkBoxDrawNode = new cc.DrawNode();
					this.addChild(this.atkBoxDrawNode, 1000);
				}
			}
		}
		if (this.colBoxDrawNode)
			this.colBoxDrawNode.setVisible(this.showColAtkBox);
		if (this.atkBoxDrawNode)
			this.atkBoxDrawNode.setVisible(this.showColAtkBox);
	},

	updateColAtkBoxRect : function() {
		if (this.showColAtkBox)
		{
			let colBox = this.getCollisionBox();
			let atkBox = this.getAttackBox();
			colBox.origin.y = -colBox.origin.y;
			atkBox.origin.y = -atkBox.origin.y;
			if (this.isFlippedX()) {
				colBox.origin.x = -(colBox.origin.x + colBox.size.width);
				atkBox.origin.x = -(atkBox.origin.x + atkBox.size.width);
			}
			let p = cc.p(colBox.origin.x+colBox.size.width, colBox.origin.y-colBox.size.height);
			this.colBoxDrawNode.clear();
			/**
			 * draws a rectangle given the origin and destination point measured in points.
			 * @param {cc.Point} origin
			 * @param {cc.Point} destination
			 * @param {cc.Color} fillColor
			 * @param {Number} lineWidth
			 * @param {cc.Color} lineColor
			 */
			this.colBoxDrawNode.drawRect(colBox.origin, p, cc.color(0,255,0,255));
			p= cc.p(atkBox.origin.x + atkBox.size.width, atkBox.origin.y -atkBox.size.height);
			this.atkBoxDrawNode.clear();
			this.atkBoxDrawNode.drawRect(atkBox.origin, p, cc.color(255,0,0,255));
		}
	},

	//nativ版本不会调用visit，使用update代替
	update : function(dt) {
		this._super(dt);
		if (!this._selfUpdate || cc.sys.isNative) {
			this.updateChildrenSprite();
			this.updateAnimation();
			this.updateColAtkBoxRect();
			++this.lifeTimer_;
		}
	},

	visit : function(parent) {
		if (this._selfUpdate) {
			this.updateChildrenSprite();
			this.updateAnimation();
			this.updateColAtkBoxRect();
			++this.lifeTimer_;
		}
		this._super(parent);
	},
	// //////////////////////////////////////////////////////////////////////////
	setUseCustomFSHShader : function(fileName) {
		this._customFSHShaderFileName = fileName;
		this.setCascadeOpacityEnabled(true);
		for (let s of this._playerAniChildrenVec) {
			if (fileName.length > 0) {
				let glp = cc.GLProgramState.getOrCreateWithGLProgram(fileName);
				if (glp) {
					s.setGLProgramState(glp);
				}
			}
		}
	},
	// //////////////////////////////////////////////////////////////////////////
	setUniformInt : function(uniformName, value) {
		for (let s of this._playerAniChildrenVec) {
			s.getGLProgramState().setUniformInt(uniformName, value);
		}
	},
	setUniformFloat : function(uniformName,value) {
		for (let s of this._playerAniChildrenVec) {
			s.getGLProgramState().setUniformFloat(uniformName, value);
		}
	},
	setUniformVec2 : function(uniformName, value) {
		for (let s of this._playerAniChildrenVec) {
			s.getGLProgramState().setUniformVec2(uniformName, value);
		}
	},
	setUniformVec3 : function(uniformName, value) {
		for (let s of this._playerAniChildrenVec) {
			s.getGLProgramState().setUniformVec3(uniformName, value);
		}
	},
	setUniformVec4 : function(uniformName, value) {
		for (let s of this._playerAniChildrenVec) {
			s.getGLProgramState().setUniformVec4(uniformName, value);
		}
	},
	setUniformMat4 : function(uniformName, value) {
		for (let s of this._playerAniChildrenVec) {
			s.getGLProgramState().setUniformMat4(uniformName, value);
		}
	},
	setUniformTexture : function(uniformName, texture) {
		for (let s of this._playerAniChildrenVec) {
			s.getGLProgramState().setUniformTexture(uniformName, texture);
		}
	},
	//////////////////////////////////////////////////////////////////////////
	addOverlapShaderSprite : function(destImgIndex, createFunc, updateFunc) {
		this._createOverlapShaderSpriteFuncMap.set(destImgIndex, createFunc);
		this._updateOverlapShaderSpriteFuncMap[destImgIndex] = updateFunc;
		if (!this._runningShaderSpriteMap.has(destImgIndex)) {
			let ossd = new ivy.ClipAniPlayer.OverlapShaderSpriteData();
			ossd.curRunningIndex = 0;
			this._runningShaderSpriteMap.set(destImgIndex, ossd);
		}
	},
	setOverlapShaderSpriteUpdateEndFunc : function(destImageIndex, endUpdateFunc) {
		this._updateEndOverlapShaderSpriteFuncMap.set(destImageIndex, endUpdateFunc);
	},
	getGoAttackSequenceFrame : function() {
		let seqCount = this._animationData.getActionSequenceCount(this.actionID_);
		let seqIndex = this._animationData.getSequenceIndex(this.actionID_, this._sequenceID);
		let sequenceDuration = this._animationData.getSequenceDuration(seqIndex);
		let controlSpeed = ivy.GlobleConfig.getInstance().getAnimationControlSpeed();
		let returnV = 0;
		let curAtkBoxData = this._animationData.getAttackBox(this.actionID_, this._sequenceID);{
			if (curAtkBoxData.size.width > 0 && curAtkBoxData.size.height > 0) {
				return returnV;
			}
		}
		returnV = sequenceDuration*controlSpeed - this._actionSequenceDuration;
		for (let i = this.sequenceID+1; i < seqCount; ++i) {
			seqIndex = this._animationData.getSequenceIndex(this.actionID_, i);
			sequenceDuration = this._animationData.getSequenceDuration(seqIndex);
			let atkBoxData = this._animationData.getAttackBox(this.actionID_, i);
			if (atkBoxData.size.width > 0 && atkBoxData.size.height > 0) {
				return returnV;
			}
			returnV += sequenceDuration*controlSpeed;
		}
		return 10000;
	},
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////private:
	isNeedUpdateOverlapShaderSprite : function(maskNum) {
		return this._createOverlapShaderSpriteFuncMap.has(maskNum);
	},
	isNeedUpdateSequence : function() {
		let seqIndex = this._animationData.getSequenceIndex(this.actionID_, this._sequenceID);
		let sequenceDuration = this._animationData.getSequenceDuration(seqIndex);
		let controlSpeed = ivy.GlobleConfig.getInstance().getAnimationControlSpeed();
		return !(this._actionSequenceDuration < (sequenceDuration + this._exDuration)*controlSpeed);
	},
	updateAnimation : function() {
		if (!this._animationData)
			return;
		if (this._playState !== ivy.AniPlayState.ePause) {
			this._actionSequenceDuration += this.getMotionValue();
		} else {
			this._isPlayEnd = true;
			if (this._playOverFunc) {
				this._playOverFunc(0);
			}
			return;
		}
		if (!this.isNeedUpdateSequence()) {
			return;
		}
		this._exDuration = 0;
		this._actionSequenceDuration = 0;

		if (this._playType === ivy.AniPlayType.eNormal) {
			++this._sequenceID;
			if (this._playState === ivy.AniPlayState.eCircle) {
				this.setNeedRefreshSpriteChildren(true);
				if (this._animationData.getActionSequenceCount(this.actionID_) <= 0) {
					this._sequenceID = 0;
				} else {
					this._sequenceID %= this._animationData.getActionSequenceCount(this.actionID_);
				}
			} else if(this._playState===ivy.AniPlayState.eNotCircle) {
				if (this._sequenceID >= this._animationData.getActionSequenceCount(this.actionID_)){
					--this._sequenceID;
					if (!this._isPlayEnd) {
						this._isPlayEnd = true;
						if (this._playOverFunc) {
							this._playOverFunc(0);
						}
					}
				} else {
					this.setNeedRefreshSpriteChildren(true);
				}
			}
		} else if (this._playType === ivy.AniPlayType.eReverse) {
			--this._sequenceID;
			if (this._playState === ivy.AniPlayState.eCircle) {
				this.setNeedRefreshSpriteChildren(true);
				if(this._sequenceID<0) {
					this._sequenceID = this._animationData.getActionSequenceCount(this.actionID_)-1;
				}
			} else if (this._playState === ivy.AniPlayState.eNotCircle) {
				if (this._sequenceID < 0) {
					++this._sequenceID;
					if (!this._isPlayEnd) {
						this._isPlayEnd = true;
						if (this._playOverFunc) {
							this._playOverFunc(0);
						}
					}
				} else {
					this.setNeedRefreshSpriteChildren(true);
				}
			}
		}
	},
	updateChildrenSprite : function() {
		if (!this._needRefreshSpriteChildren)
			return;
		let frameID = this._animationData.getFrameID(this.actionID_, this._sequenceID);
		let frameSpriteCount = this._animationData.getFrameSpriteCount(frameID);
		let soundID = this._animationData.getSoundID(this.actionID_, this._sequenceID);
		if (soundID >= 0) {
			ivy.SoundManager.getInstance().playSound(soundID);
		}
		let spriteIndex = 0;
		let scdm = ivy.SceneCommonDataManager.getInstance();
		for (let i = 0; i < frameSpriteCount; ++i) {
			let curSprite = this._playerAniChildrenVec.get(i);
			spriteIndex= this._animationData.getFrameSpriteOffset(frameID)+ i;
			let flipV = this._animationData.getSpriteFlip(spriteIndex);
			let posV = this._animationData.getSpritePosition(spriteIndex);
			let exDataV = this._animationData.getSpriteExDataIndex(spriteIndex);

			//此处需添加对粒子的支持。。。
			let moduleID = this._animationData.getSpriteModuleID(spriteIndex);
			let imgID = this._animationData.getModuleImgID(moduleID);

			let imgName = this._animationData.getSrcImageName(imgID);
			let imgSrcName = imgName;
			let maskNum = scdm.getImageMaskByName(imgSrcName);
			if (this._suitChangeMap.has(imgID)) {
				let suitID = this._suitChangeMap.get(imgID);
				if (this._animationData.isSuitIDVaild(imgID, suitID)) {
					imgName = this._animationData.getSuitImageName(imgID,suitID)+".png";
				}
			}
			let moduleRect = this._animationData.getModuleRect(moduleID);

			let imgFullPath = scdm.getClipAnimationTextureFullPath(imgName);
			let tex = null;
			if (ivy.GlobleConfig.getInstance().isEnableAnimationEncryp()){
				tex = ivy.EncryptManager.getInstance().addEncryptImage(imgFullPath);
			} else {
				tex = cc.textureCache.getTextureForKey(imgFullPath);
				if (!tex) {
					tex = cc.textureCache.addImage(imgFullPath);
				}
			}

			tex.setAntiAliasTexParameters();
			if (this._customFSHShaderFileName.length <= 0) {
				curSprite.setTexture(tex);
			} else {
				curSprite.setTextureWithCustomGLShader(tex, this._customFSHShaderFileName);
			}

			curSprite.setTextureRect(moduleRect, false, cc.size(moduleRect.width, moduleRect.height));
			if (scdm.isImageNeedBlendAdditive(imgName)) {
				let blendFunc = cc.BlendFunc._additive();
				curSprite.setBlendFunc(blendFunc);
			} else {
				if (this._useCustomBlendFunc) {
					curSprite.setBlendFunc(this.blendFunc_);
				} else {
					curSprite.setBlendFunc(cc.BlendFunc._alphaPremultiplied());
				}
			}

			let invaildV = -1;
			if (exDataV !== invaildV) {
				curSprite.setOpacity(this._animationData.getTransformOpacity(exDataV));
				curSprite.setColor(this._animationData.getTransformColor(exDataV));
			} else {
				curSprite.setOpacity(255);
				curSprite.setColor(cc.color(255,255,255));
			}

			if (this.isFilppedX) {
				flipV = (flipV === ivy.EditorFilpType.eTranslateFlipNo) ? (ivy.EditorFilpType.eTranslateMirrorFlipNo)
					: ((flipV === ivy.EditorFilpType.eTranslateMirrorFlipNo) ? (ivy.EditorFilpType.eTranslateFlipNo)
						: ((flipV === ivy.EditorFilpType.eTranslateFlip180) ? (ivy.EditorFilpType.eTranslateMirrorFlip180)
							: ((flipV === ivy.EditorFilpType.eTranslateMirrorFlip180) ? (ivy.EditorFilpType.eTranslateFlip180)
								: ((flipV === ivy.EditorFilpType.eTranslateFlip270) ? (ivy.EditorFilpType.eTranslateMirrorFlip90)
									: ((flipV === ivy.EditorFilpType.eTranslateFlip90) ? (ivy.EditorFilpType.eTranslateMirrorFlip270)
										: (flipV))))));
				if (flipV === ivy.EditorFilpType.eTranslateMirrorFlip90 || flipV === ivy.EditorFilpType.eTranslateMirrorFlip270) {
					posV.x = -posV.x - moduleRect.height;
				} else {
					posV.x = -posV.x - moduleRect.width;
				}
			}

			let ix = 0.0, iy = 0.0,mw=moduleRect.width,mh=moduleRect.height;
			switch (flipV) {
				case ivy.EditorFilpType.eTranslateFlipNo:
					curSprite.setFlippedX(false);
					curSprite.setRotation(0.0);
					ix = mw / 2.0;
					iy = -mh / 2.0;
					break;
				case ivy.EditorFilpType.eTranslateFlip90:
					curSprite.setFlippedX(false);
					curSprite.setRotation(90.0);
					ix = mh / 2.0;
					iy = -(mw / 2.0);
					break;
				case ivy.EditorFilpType.eTranslateFlip180:
					curSprite.setFlippedX(false);
					curSprite.setRotation(180.0);
					ix = mw / 2.0;
					iy = -(mh / 2.0);
					break;
				case ivy.EditorFilpType.eTranslateFlip270:
					curSprite.setFlippedX(false);
					curSprite.setRotation(270.0);
					ix = mh / 2.0;
					iy = -(mw / 2.0);
					break;
				case ivy.EditorFilpType.eTranslateMirrorFlipNo:
					curSprite.setFlippedX(true);
					curSprite.setRotation(0.0);
					ix = mw / 2.0;
					iy = -(mh / 2.0);
					break;
				case ivy.EditorFilpType.eTranslateMirrorFlip90:
					curSprite.setFlippedX(true);
					curSprite.setRotation(90.0);
					ix = mh / 2.0;
					iy = -(mw / 2.0);
					break;
				case ivy.EditorFilpType.eTranslateMirrorFlip180:
					curSprite.setFlippedX(true);
					curSprite.setRotation(180.0);
					ix = mw / 2.0;
					iy = -(mh / 2.0);
					break;
				case ivy.EditorFilpType.eTranslateMirrorFlip270:
					curSprite.setFlippedX(true);
					curSprite.setRotation(270.0);
					ix = mh / 2.0;
					iy = -(mw / 2.0);
					break;
				default:
					curSprite.setFlippedX(false);
					curSprite.setRotation(0.0);
					ix = mw / 2.0;
					iy = -(mh / 2.0);
					break;
			}
			let drawPosX = posV.x + ix;
			let drawPosY = posV.y + iy;

			if (exDataV !== invaildV) {
				let exRotate = this._animationData.getTransformRotation(exDataV);
				if (this.isFlippedX()) {
					exRotate = 360 - exRotate;
				}
				curSprite.setRotation(curSprite.getRotation()+ exRotate);
				curSprite.setScaleX(this._animationData.getTransformScaleX(exDataV));
				curSprite.setScaleY(this._animationData.getTransformScaleY(exDataV));
			} else {
				curSprite.setScale(1.0);
			}
			curSprite.setPosition(drawPosX, drawPosY);
			if(!curSprite.isVisible()) {
				curSprite.setVisible(true);
			}
			if (this.isNeedUpdateOverlapShaderSprite(maskNum)) {
				let overlapShaderSpriteData = this._runningShaderSpriteMap.get(maskNum);
				++overlapShaderSpriteData.curRunningIndex;
				if (overlapShaderSpriteData.runningShaderSpriteVec.length < overlapShaderSpriteData.curRunningIndex) {
					overlapShaderSpriteData.runningShaderSpriteVec.push(this._createOverlapShaderSpriteFuncMap.get(maskNum)(this));
				}
				this._updateOverlapShaderSpriteFuncMap[maskNum](curSprite, overlapShaderSpriteData.runningShaderSpriteVec[overlapShaderSpriteData.curRunningIndex-1]);
				if (this._updateEndOverlapShaderSpriteFuncMap.has(maskNum)) {
					this._updateEndOverlapShaderSpriteFuncMap.get(maskNum)(curSprite, overlapShaderSpriteData.runningShaderSpriteVec[overlapShaderSpriteData.curRunningIndex - 1]);
				}
			}
			if (this._customUpdateAniChildrenSpriteFunc) {
				this._customUpdateAniChildrenSpriteFunc(imgSrcName, curSprite, this);
			}
		}
		let allSpriteCount = this._playerAniChildrenVec.size();
		for (let j = frameSpriteCount; j < allSpriteCount; ++j) {
			this._playerAniChildrenVec.get(j).setVisible(false);
		}
		for (let value of this._runningShaderSpriteMap.values()) {
			let vec = value.runningShaderSpriteVec;
			for (let j = value.curRunningIndex; j < vec.length; ++j) {
				vec[j].setVisible(false);
			}
			value.curRunningIndex = 0;
		}
		this.setNeedRefreshSpriteChildren(false);
	},
	initAllPlayerAniChildren : function() {
		this.removeAllChildren();
		for (let value of this._runningShaderSpriteMap.values()) {
			value.runningShaderSpriteVec = [];
		}

		if (this.showColAtkBox) {
			this.setShowColAtkBoxRect(true,true);
		}
		this._playerAniChildrenVec.clear();
		if (this._animationData) {
			let frameMaxCount = this._animationData.getFrameSpriteMaxCount();
			for (let i = 0; i < frameMaxCount; ++i) {
				let s = new cc.Sprite();
				//可通过函数对象设定进行对象创建的类型改变
				this.addChild(s,i);
				this._playerAniChildrenVec.set(i, s);
			}
		}
	},

	_runningLightVec : null,
	_customFSHShaderFileName : "",
	_createOverlapShaderSpriteFuncMap : null,//std::map
	_updateOverlapShaderSpriteFuncMap : null,//{}
	_updateEndOverlapShaderSpriteFuncMap : null,//std::map
	_runningShaderSpriteMap : null,//std::map
});

ivy.ClipAniPlayer.create = function (ani, actionID=0, sequenceID=0, selfUpdate=true, playState=ivy.AniPlayState.eCircle, playType=ivy.AniPlayType.eNormal) {
	if (ani instanceof ivy.AnimationID) {
		return this.create(ani.classID, ani.actionID, ani.sequenceID, ani.selfUpdate, ani.playState, ani.playType);
	} else {
		let classID = null;
		let animationDataPtr = null;
		if (cc.isNumber(ani)) {
			classID = ani;
			animationDataPtr = ivy.EditorDataManager.getInstance().getAnimationDataBy(classID);
		} else if (cc.isString(ani)) {
			let aniFileName = ani;
			classID = ivy.SceneCommonDataManager.getInstance().getClassIDByAniFileName(aniFileName);
			animationDataPtr = ivy.EditorDataManager.getInstance().getAnimationDataBy(aniFileName);
		}
		if (animationDataPtr) {
			let aniplayerPtr= new ivy.ClipAniPlayer();
			aniplayerPtr.init();
			aniplayerPtr.setAnimationID(classID);
			aniplayerPtr.setAnimationData(animationDataPtr);
			aniplayerPtr.setActionID(actionID);
			aniplayerPtr.setSequenceID(sequenceID);
			aniplayerPtr.setPlayState(playState);
			aniplayerPtr.setPlayType(playType);
			aniplayerPtr.initAllPlayerAniChildren();
			aniplayerPtr.setCascadeColorEnabled(true);
			aniplayerPtr.setCascadeOpacityEnabled(true);
			aniplayerPtr.setSelfUpdate(selfUpdate);
			return aniplayerPtr;
		}
	}
	return null;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(function () {
	ivy.ClipAniPlayer.OverlapShaderSpriteData = function () {
		//成员变量
		this.curRunningIndex = 0;
		this.runningShaderSpriteVec = [];
	};
})();
